package test;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: fzykd
 * Date: 2023-01-10
 * Time: 20:55
 */
class MyBlockQueue{
    //定义数组大小
    private int[] arr = new int[1000];
    //定义头指针
    private int head;
    //定义尾指针
    private int tail;
    //定义存入的有效数据个数
    private int size;

    //实现阻塞
    private Object locker = new Object();

    //入队列
    public void push(int val) throws InterruptedException {
        synchronized (locker){
            //首先判断满不满
            if (size == arr.length){
                //满了阻塞等待
                locker.wait();
            }
            //不满 添加  尾进
            arr[tail] = val;
            tail++;
            //处理尾走到数组最后一个位置
            if (tail >= arr.length){
                tail = 0;
            }
            //有效数据++
            size++;
            locker.notify();
        }
    }

    //出队列
    public Integer take() throws InterruptedException {
       synchronized (locker){
           //判断空不空
           if (size == 0) {
               //空了 阻塞的等待
               locker.wait();
           }
           //不空 出队列
           int ret = arr[head];
           head++;
           if (head >= arr.length) {
               head = 0;
           }
           size--;
           locker.notify();
           return ret;
       }
    }
}

//阻塞队列 - 基于循环队列 和 wait notify实现
public class Demo3 {

    private static MyBlockQueue queue = new MyBlockQueue();
    //基于以上的阻塞队列 实现生产者 消费者模型
    public static void main(String[] args) {
        Thread producer = new Thread(()->{
            int n = 0;
            while (true){
                n++;
                try {
                    queue.push(n);
                    System.out.println("生产了" + n);
                    //Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        producer.start();
        //消费者
        Thread consumer = new Thread(()->{
            while (true){
                int n = 0;
                try {
                    n = queue.take();
                    System.out.println("消费了: " + n);
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        consumer.start();
    }

    //验证循环队列
    public static void main1(String[] args) throws InterruptedException {
        MyBlockQueue queue = new MyBlockQueue();
        queue.push(10);
        queue.push(20);
        queue.push(30);

        //队列 先进先出
        System.out.println(queue.take());
        System.out.println(queue.take());
        System.out.println(queue.take());

    }
}
